#include <functional>
#include"Socket.hpp"
#include "ServerCal.hpp"


using func_t = std::function<std::string (std::string& package)>;

class TcpServer
{
public:

    TcpServer(uint16_t port,func_t callback)
        :port_(port),callback_(callback)
    {}
    void Init()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        lg(INFO,"Server Init");
    }

    void Start()
    {
        while(true)
        {
            std::string ip;
            uint16_t port;
            int fd = listensock_.Accept(&ip,&port);
            lg(INFO,"Server Accept");

            if(fork() == 0)
            {
                lg(INFO,"fork success");
                listensock_.Close();    
                std::string inbuffer_stream;
                while(true)
                {
                    char buffer[1024];
                    int n = read(fd,&buffer,sizeof(buffer));
                    // int n = read(listensock_.GetFd(),&buffer,sizeof(buffer));
                    if(n > 0)
                    {
                        lg(INFO,"read success");
                        buffer[n] = 0;
                        
                        inbuffer_stream += buffer;
                        //std::cout << "inbuffer_stream"<< inbuffer_stream <<std::endl;
                        
                        while(true)
                        {
                            std::string info =  callback_(inbuffer_stream);
                            if(info.empty()) break;
                            //std::cout <<"info"<< info <<std::endl;
                            //sleep(3);

                            write(fd,info.c_str(),info.size());
                        }
   
                    }
                    else if(n == 0) break;
                    else 
                        break;

                }
                
                
                exit(0);
            }

            close(fd);
        }
    }
private:
    uint16_t port_;
    Sock listensock_;
    func_t callback_;

};